-babl 0.1.34
+babl 0.1.38
Dynamic; any to any, pixel format conversion library.
installation (or a variation on this theme):
------------------------------------------------------------
- foo$ wget ftp://ftp.gtk.org/pub/babl/0.1/babl-0.1.34.tar.bz2
- foo$ tar jxf babl-0.1.34.tar.gz
- foo$ cd babl-0.1.34
- foo/babl-0.1.34$ ./configure && make && sudo make install
+ foo$ wget ftp://ftp.gtk.org/pub/babl/0.1/babl-0.1.38.tar.bz2
+ foo$ tar jxf babl-0.1.38.tar.gz
+ foo$ cd babl-0.1.38
+ foo/babl-0.1.38$ ./configure && make && sudo make install
------------------------------------------------------------
<dl><dt><!--
The NEWS file in the babl source tree is the source location for
the news section both in the README and the webpage.
-
-
-->
+
+2017-11-15 babl-0.1.38 </dt><dd>
+Added format "CIE L float", a couple of protections against division by 0.0
+ </dd><dt>
+2017-11-10 babl-0.1.36 </dt><dd>
+Optimized customized primary aware code paths for CIE Lab<->RGB conversions,
+improved accuracy of gamma approximations. New API babl_format_exists() for
+checking validity of babl format name, crash proofing of cache handling and use
+of environment variables.
+ </dd><dt>
2017-10-06 babl-0.1.34 </dt><dd>
Brown paper bag release, Fix indexed / custom primaries conflict, and re-export
a symbol used by old GEGL/GIMPs.
-Babl-0.1.34
+Babl-0.1.38
Contents
release is done a babl release is most often put out just prior to the
GEGL release.
+2017-11-15 babl-0.1.38
+ Added format "CIE L float", a couple of protections against
+ division by 0.0
+2017-11-10 babl-0.1.36
+ Optimized customized primary aware code paths for CIE Lab<->RGB
+ conversions, improved accuracy of gamma approximations. New API
+ babl_format_exists() for checking validity of babl format name,
+ crash proofing of cache handling and use of environment variables.
2017-10-06 babl-0.1.34
Brown paper bag release, Fix indexed / custom primaries conflict,
and re-export a symbol used by old GEGL/GIMPs.
float CIE b
float A
+CIE L float
+
+bytes/pixel
+ 4
+model
+ CIE Lab
+components
+
+ float CIE L
+
CIE L alpha float
bytes/pixel
Ell
fast paths
-/babl-0.1.34
+/babl-0.1.38
{
char copy[4096];
strncpy (copy, path, 4096);
+ copy[sizeof (copy) - 1] = '\0';
if (strrchr (copy, '/'))
{
*strrchr (copy, '/') = '\0';
{
char copy[4096];
strncpy (copy, path, 4096);
+ copy[sizeof (copy) - 1] = '\0';
#ifdef _WIN32
for (char *c = copy; *c; c++)
if (*c == '\\')
static char path[4096];
strncpy (path, FALLBACK_CACHE_PATH, 4096);
+ path[sizeof (path) - 1] = '\0';
#ifndef _WIN32
if (getenv ("XDG_CACHE_HOME"))
- sprintf (path, "%s/babl/babl-fishes", getenv("XDG_CACHE_HOME"));
+ snprintf (path, sizeof (path), "%s/babl/babl-fishes", getenv("XDG_CACHE_HOME"));
else if (getenv ("HOME"))
- sprintf (path, "%s/.cache/babl/babl-fishes", getenv("HOME"));
+ snprintf (path, sizeof (path), "%s/.cache/babl/babl-fishes", getenv("HOME"));
#else
{
char win32path[4096];
if (SHGetFolderPathA (NULL, CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_CURRENT, win32path) == S_OK)
- sprintf (path, "%s\\%s\\babl-fishes.txt", win32path, BABL_LIBRARY);
+ snprintf (path, sizeof (path), "%s\\%s\\babl-fishes.txt", win32path, BABL_LIBRARY);
else if (getenv ("TEMP"))
- sprintf (path, "%s\\babl-fishes.txt", getenv("TEMP"));
+ snprintf (path, sizeof (path), "%s\\babl-fishes.txt", getenv("TEMP"));
}
#endif
{
static char buf[2048];
if (strchr (BABL_GIT_VERSION, ' ')) // we must be building from tarball
- sprintf (buf, "#%i.%i.%i BABL_PATH_LENGTH=%d BABL_TOLERANCE=%f",
+ snprintf (buf, sizeof (buf),
+ "#%i.%i.%i BABL_PATH_LENGTH=%d BABL_TOLERANCE=%f",
BABL_MAJOR_VERSION, BABL_MINOR_VERSION, BABL_MICRO_VERSION,
_babl_max_path_len (), _babl_legal_error ());
else
- sprintf (buf, "#%s BABL_PATH_LENGTH=%d BABL_TOLERANCE=%f",
- BABL_GIT_VERSION,
- _babl_max_path_len (), _babl_legal_error ());
+ snprintf (buf, sizeof (buf), "#%s BABL_PATH_LENGTH=%d BABL_TOLERANCE=%f",
+ BABL_GIT_VERSION, _babl_max_path_len (), _babl_legal_error ());
return buf;
}
char *tmpp = calloc(8000,1);
FILE *dbfile;
- sprintf (tmpp, "%s~", fish_cache_path ());
+ if (!tmpp)
+ return;
+ snprintf (tmpp, 8000, "%s~", fish_cache_path ());
dbfile = fopen (tmpp, "w");
if (!dbfile)
+ {
+ free (tmpp);
return;
+ }
fprintf (dbfile, "%s\n", cache_header ());
/* sort the list of fishes by usage, making next run more efficient -
{
fprintf (stderr, "%s:%i: loading of cache failed\n",
__FUNCTION__, __LINE__);
+ free (contents);
return;
}
Babl *conv = (void*)babl_db_find(babl_conversion_db(), &token[1]);
if (!conv)
{
+ free (contents);
return;
}
else
{
if (babl_extender ())
{
- snprintf (buf, 512 - 1, "%s %i: %s%s to %s",
+ snprintf (buf, sizeof (buf), "%s %i: %s%s to %s",
BABL (babl_extender ())->instance.name,
collisions,
type == BABL_CONVERSION_LINEAR ? "" :
type == BABL_CONVERSION_PLANAR ? "planar " : "Eeeek! ",
source->instance.name,
destination->instance.name);
- buf[511] = '\0';
}
else
{
- snprintf (buf, 512 - 1, "%s %s to %s %i",
+ snprintf (buf, sizeof (buf), "%s %s to %s %i",
type == BABL_CONVERSION_LINEAR ? "" :
type == BABL_CONVERSION_PLANE ? "plane " :
type == BABL_CONVERSION_PLANAR ? "planar " : "Eeeek! ",
source->instance.name,
destination->instance.name,
collisions);
- buf[511] = '\0';
}
return buf;
}
{
Babl *ret;
char new_name[256];
- sprintf (new_name, "%s-%s", babl_get_name ((void*)format),
- babl_get_name ((void*)space));
+ snprintf (new_name, sizeof (new_name), "%s-%s", babl_get_name ((void*)format),
+ babl_get_name ((void*)space));
ret = babl_db_find (babl_format_db(), new_name);
if (ret)
return ret;
{
char buf[512] = "";
char *p = &buf[0];
+ ssize_t left;
int i;
int same_types = 1;
const BablType**t = type;
BablComponent **c1 = component;
BablComponent **c2 = model->component;
-
- sprintf (p, "%s ", model->instance.name);
+ left = 512;
+ snprintf (p, left, "%s ", model->instance.name);
p += strlen (model->instance.name) + 1;
+ left -= strlen (model->instance.name) + 1;
+ babl_assert (left >= 0);
i = components;
while (i--)
if (same_types)
{
- sprintf (p, "%s", first_type->instance.name);
+ snprintf (p, left, "%s", first_type->instance.name);
return babl_strdup (buf);
}
while (i--)
{
- sprintf (p, "(%s as %s) ",
+ snprintf (p, left, "(%s as %s) ",
(*component)->instance.name,
(*type)->instance.name);
p += strlen ((*component)->instance.name) +
strlen ((*type)->instance.name) + strlen ("( as ) ");
+ left -= strlen ((*component)->instance.name) +
+ strlen ((*type)->instance.name) + strlen ("( as ) ");
+ babl_assert (left >= 0);
component++;
type++;
}
int components)
{
char buf[512];
- sprintf (buf, "%s[%i] ", type->instance.name, components);
+ snprintf (buf, sizeof (buf), "%s[%i] ", type->instance.name, components);
return babl_strdup (buf);
}
return ret;
}
+int
+babl_format_exists (const char *name)
+{
+ if (babl_db_exist_by_name (db, name))
+ return 1;
+ return 0;
+}
+
+
{
char tag[5];
int val = icc_read (u32, 64);
- sprintf (tag, "%i", val);
+ snprintf (tag, sizeof (tag), "%i", val);
return strdup (tag);
} else if (!strcmp (key, "tags"))
{
{
char buf[512];
- sprintf (buf, "echo bt>/tmp/babl.gdb;"
+ snprintf (buf, sizeof (buf), "echo bt>/tmp/babl.gdb;"
"gdb -q --batch -x /tmp/babl.gdb --pid=%i | grep 'in ''babl_die' -A40", getpid ());
return system (buf);
}
{
static char buf[128];
- sprintf (buf, "mallocs:%i callocs:%i strdups:%i dups:%i allocs:%i frees:%i reallocs:%i\t|",
+ snprintf (buf, sizeof (buf), "mallocs:%i callocs:%i strdups:%i dups:%i allocs:%i frees:%i reallocs:%i\t|",
mallocs, callocs, strdups, dups, mallocs + callocs + strdups + dups, frees, reallocs);
return buf;
}
if (!name)
{
static int cnt = 0;
- sprintf (cname, "_babl-int-%i", cnt++);
+ snprintf (cname, sizeof (cname), "_babl-int-%i", cnt++);
name = cname;
}
else
space_db[i]=space;
space_db[i].instance.name = space_db[i].name;
if (name)
- sprintf (space_db[i].name, "%s", name);
+ snprintf (space_db[i].name, sizeof (space_db[i].name), "%s", name);
else
- sprintf (space_db[i].name, "space-%.4f,%.4f_%.4f,%.4f_%.4f_%.4f,%.4f_%.4f,%.4f_%s,%s,%s",
+ snprintf (space_db[i].name, sizeof (space_db[i].name), "space-%.4f,%.4f_%.4f,%.4f_%.4f_%.4f,%.4f_%.4f,%.4f_%s,%s,%s",
rx, gx, bx,
ry, gy, by,
rz, gz, bz,
space_db[i]=space;
space_db[i].instance.name = space_db[i].name;
if (name)
- sprintf (space_db[i].name, "%s", name);
+ snprintf (space_db[i].name, sizeof (space_db[i].name), "%s", name);
else
/* XXX: this can get longer than 256bytes ! */
- sprintf (space_db[i].name, "space-%.4f,%.4f_%.4f,%.4f_%.4f,%.4f_%.4f,%.4f_%s,%s,%s",
+ snprintf (space_db[i].name, sizeof (space_db[i].name),
+ "space-%.4f,%.4f_%.4f,%.4f_%.4f,%.4f_%.4f,%.4f_%s,%s,%s",
wx,wy,rx,ry,bx,by,gx,gy,babl_get_name (space.trc[0]),
babl_get_name(space.trc[1]), babl_get_name(space.trc[2]));
trc_db[i]=trc;
trc_db[i].instance.name = trc_db[i].name;
if (name)
- sprintf (trc_db[i].name, "%s", name);
+ snprintf (trc_db[i].name, sizeof (trc_db[i].name), "%s", name);
else if (n_lut)
- sprintf (trc_db[i].name, "lut-trc");
+ snprintf (trc_db[i].name, sizeof (trc_db[i].name), "lut-trc");
else
- sprintf (trc_db[i].name, "trc-%i-%f", type, gamma);
+ snprintf (trc_db[i].name, sizeof (trc_db[i].name), "trc-%i-%f", type, gamma);
if (n_lut)
{
fabs (c - (-3417)) < 0.01)
return babl_trc ("sRGB");
- sprintf (name, "%.6f %.6f %.4f %.4f %.4f", g, a, b, c, d);
+ snprintf (name, sizeof (name), "%.6f %.6f %.4f %.4f %.4f", g, a, b, c, d);
for (i = 0; name[i]; i++)
if (name[i] == ',') name[i] = '.';
while (name[strlen(name)-1]=='0')
if (fabs (gamma - 1.0) < 0.01)
return babl_trc_new ("linear", BABL_TRC_LINEAR, 1.0, 0, NULL);
- sprintf (name, "%.6f", gamma);
+ snprintf (name, sizeof (name), "%.6f", gamma);
for (i = 0; name[i]; i++)
if (name[i] == ',') name[i] = '.';
while (name[strlen(name)-1]=='0')
if (!file)
return -1;
- fseek (file, 0, SEEK_END);
- size = ftell (file);
+ if (fseek (file, 0, SEEK_END) == -1 || (size = ftell (file)) == -1)
+ {
+ fclose (file);
+ return -1;
+ }
if (length) *length = size;
rewind (file);
+ if ((size_t) size > SIZE_MAX - 8)
+ {
+ fclose (file);
+ return -1;
+ }
buffer = calloc(size + 8, 1);
if (!buffer)
#define BABL_MAJOR_VERSION 0
#define BABL_MINOR_VERSION 1
-#define BABL_MICRO_VERSION 34
+#define BABL_MICRO_VERSION 38
/** Get the version information on the babl library */
void babl_get_version (int *major,
*/
const Babl * babl_format (const char *name);
+/**
+ * babl_format_exists:
+ *
+ * Returns 1 if the provided format name is known by babl or 0 if it is
+ * not. Can also be used to verify that specific extension formats are
+ * available (though this can also be inferred from the version of babl).
+ */
+int babl_format_exists (const char *name);
+
/**
* babl_format_with_space:
*
double
babl_pow_24 (double x)
{
- double y = init_newton (x, -1./5, 0.9953189663, 0.9594345146, 0.6742970332);
+ double y;
int i;
+ if (x > 16.0) {
+ /* for large values, fall back to a slower but more accurate version */
+ return exp (log (x) * 2.4);
+ }
+ y = init_newton (x, -1./5, 0.9953189663, 0.9594345146, 0.6742970332);
for (i = 0; i < 3; i++)
y = (1.+1./5)*y - ((1./5)*x*(y*y))*((y*y)*(y*y));
x *= y;
double
babl_pow_1_24 (double x)
{
- double y = init_newton (x, -1./12, 0.9976800269, 0.9885126933, 0.5908575383);
+ double y;
int i;
double z;
+ if (x > 1024.0) {
+ /* for large values, fall back to a slower but more accurate version */
+ return exp (log (x) * (1.0 / 2.4));
+ }
+ y = init_newton (x, -1./12, 0.9976800269, 0.9885126933, 0.5908575383);
x = sqrt (x);
/* newton's method for x^(-1/6) */
z = (1./6.) * x;
float
babl_pow_24f (float x)
{
- float y = init_newtonf (x, -1.f/5, 0.9953189663f, 0.9594345146f, 0.6742970332f);
+ float y;
int i;
+ if (x > 16.0f) {
+ /* for large values, fall back to a slower but more accurate version */
+ return expf (logf (x) * 2.4f);
+ }
+ y = init_newtonf (x, -1.f/5, 0.9953189663f, 0.9594345146f, 0.6742970332f);
for (i = 0; i < 3; i++)
- y = (1.f+1.f/5)*y - ((1./5)*x*(y*y))*((y*y)*(y*y));
+ y = (1.f+1.f/5)*y - ((1.f/5)*x*(y*y))*((y*y)*(y*y));
x *= y;
return x*x*x;
}
float
babl_pow_1_24f (float x)
{
- float y = init_newtonf (x, -1.f/12, 0.9976800269f, 0.9885126933f, 0.5908575383f);
+ float y;
int i;
float z;
+ if (x > 1024.0f) {
+ /* for large values, fall back to a slower but more accurate version */
+ return expf (logf (x) * (1.0f / 2.4f));
+ }
+ y = init_newtonf (x, -1.f/12, 0.9976800269f, 0.9885126933f, 0.5908575383f);
x = sqrtf (x);
/* newton's method for x^(-1/6) */
z = (1.f/6.f) * x;
static inline double
babl_pow_24 (double x)
{
- double y = init_newton (x, -1./5, 0.9953189663, 0.9594345146, 0.6742970332);
+ double y;
int i;
+ if (x > 16.0) {
+ /* for large values, fall back to a slower but more accurate version */
+ return exp (log (x) * 2.4);
+ }
+ y = init_newton (x, -1./5, 0.9953189663, 0.9594345146, 0.6742970332);
for (i = 0; i < 3; i++)
y = (1.+1./5)*y - ((1./5)*x*(y*y))*((y*y)*(y*y));
x *= y;
static inline double
babl_pow_1_24 (double x)
{
- double y = init_newton (x, -1./12, 0.9976800269, 0.9885126933, 0.5908575383);
+ double y;
int i;
double z;
+ if (x > 1024.0) {
+ /* for large values, fall back to a slower but more accurate version */
+ return exp (log (x) * (1.0 / 2.4));
+ }
+ y = init_newton (x, -1./12, 0.9976800269, 0.9885126933, 0.5908575383);
x = sqrt (x);
/* newton's method for x^(-1/6) */
z = (1./6.) * x;
static inline float
babl_pow_24f (float x)
{
- float y = init_newtonf (x, -1.f/5, 0.9953189663f, 0.9594345146f, 0.6742970332f);
+ float y;
int i;
+ if (x > 16.0f) {
+ /* for large values, fall back to a slower but more accurate version */
+ return expf (logf (x) * 2.4f);
+ }
+ y = init_newtonf (x, -1.f/5, 0.9953189663f, 0.9594345146f, 0.6742970332f);
for (i = 0; i < 3; i++)
- y = (1.f+1.f/5)*y - ((1./5)*x*(y*y))*((y*y)*(y*y));
+ y = (1.f+1.f/5)*y - ((1.f/5)*x*(y*y))*((y*y)*(y*y));
x *= y;
return x*x*x;
}
static inline float
babl_pow_1_24f (float x)
{
- float y = init_newtonf (x, -1.f/12, 0.9976800269f, 0.9885126933f, 0.5908575383f);
+ float y;
int i;
float z;
+ if (x > 1024.0f) {
+ /* for large values, fall back to a slower but more accurate version */
+ return expf (logf (x) * (1.0f / 2.4f));
+ }
+ y = init_newtonf (x, -1.f/12, 0.9976800269f, 0.9885126933f, 0.5908575383f);
x = sqrtf (x);
/* newton's method for x^(-1/6) */
z = (1.f/6.f) * x;
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for babl 0.1.34.
+# Generated by GNU Autoconf 2.69 for babl 0.1.38.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
# Identity of this package.
PACKAGE_NAME='babl'
PACKAGE_TARNAME='babl'
-PACKAGE_VERSION='0.1.34'
-PACKAGE_STRING='babl 0.1.34'
+PACKAGE_VERSION='0.1.38'
+PACKAGE_STRING='babl 0.1.38'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures babl 0.1.34 to adapt to many kinds of systems.
+\`configure' configures babl 0.1.38 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of babl 0.1.34:";;
+ short | recursive ) echo "Configuration of babl 0.1.38:";;
esac
cat <<\_ACEOF
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-babl configure 0.1.34
+babl configure 0.1.38
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by babl $as_me 0.1.34, which was
+It was created by babl $as_me 0.1.38, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
BABL_MAJOR_VERSION=0
BABL_MINOR_VERSION=1
-BABL_MICRO_VERSION=34
+BABL_MICRO_VERSION=38
BABL_INTERFACE_AGE=1
-BABL_BINARY_AGE=134
-BABL_VERSION=0.1.34
-BABL_REAL_VERSION=0.1.34
+BABL_BINARY_AGE=138
+BABL_VERSION=0.1.38
+BABL_REAL_VERSION=0.1.38
BABL_API_VERSION=0.1
-BABL_LIBRARY_VERSION="133:1:133"
+BABL_LIBRARY_VERSION="137:1:137"
BABL_CURRENT_MINUS_AGE=0
# Define the identity of the package.
PACKAGE='babl'
- VERSION='0.1.34'
+ VERSION='0.1.38'
# Some tools Automake needs.
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by babl $as_me 0.1.34, which was
+This file was extended by babl $as_me 0.1.38, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-babl config.status 0.1.34
+babl config.status 0.1.38
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
m4_define([babl_major_version], [0])
m4_define([babl_minor_version], [1])
-m4_define([babl_micro_version], [34])
+m4_define([babl_micro_version], [38])
m4_define([babl_real_version],
[babl_major_version.babl_minor_version.babl_micro_version])
m4_define([babl_version], [babl_real_version])
babl_fast_fish
babl_fish
babl_format
+babl_format_exists
babl_format_get_bytes_per_pixel
babl_format_get_model
babl_format_get_n_components
* Copyright (C) 2005, 2014 Øyvind Kolås.
* Copyright (C) 2009, Martin Nordholts
* Copyright (C) 2014, Elle Stone
+ * Copyright (C) 2017, Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
double y_r = Y / D50_WHITE_REF_Y;
double z_r = Z / D50_WHITE_REF_Z;
- if (x_r > LAB_EPSILON) f_x = pow(x_r, 1.0 / 3.0);
+ if (x_r > LAB_EPSILON) f_x = cbrt(x_r);
else ( f_x = ((LAB_KAPPA * x_r) + 16) / 116.0 );
- if (y_r > LAB_EPSILON) f_y = pow(y_r, 1.0 / 3.0);
+ if (y_r > LAB_EPSILON) f_y = cbrt(y_r);
else ( f_y = ((LAB_KAPPA * y_r) + 16) / 116.0 );
- if (z_r > LAB_EPSILON) f_z = pow(z_r, 1.0 / 3.0);
+ if (z_r > LAB_EPSILON) f_z = cbrt(z_r);
else ( f_z = ((LAB_KAPPA * z_r) + 16) / 116.0 );
*to_L = (116.0 * f_y) - 16.0;
return f * f * f;
}
+static void
+Yf_to_Lf (const Babl *conversion,float *src,
+ float *dst,
+ long samples)
+{
+ long n = samples;
+
+ while (n--)
+ {
+ float yr = src[0];
+ float L = yr > LAB_EPSILON ? 116.0f * _cbrtf (yr) - 16 : LAB_KAPPA * yr;
+
+ dst[0] = L;
+
+ src++;
+ dst++;
+ }
+}
+
+static void
+Yaf_to_Lf (const Babl *conversion,float *src,
+ float *dst,
+ long samples)
+{
+ long n = samples;
+
+ while (n--)
+ {
+ float yr = src[0];
+ float L = yr > LAB_EPSILON ? 116.0f * _cbrtf (yr) - 16 : LAB_KAPPA * yr;
+
+ dst[0] = L;
+
+ src += 2;
+ dst += 1;
+ }
+}
+
static void
Yaf_to_Laf (const Babl *conversion,float *src,
float *dst,
float *dst,
long samples)
{
+ const Babl *space = babl_conversion_get_source_space (conversion);
+ float m_0_0 = space->space.RGBtoXYZf[0] / D50_WHITE_REF_X;
+ float m_0_1 = space->space.RGBtoXYZf[1] / D50_WHITE_REF_X;
+ float m_0_2 = space->space.RGBtoXYZf[2] / D50_WHITE_REF_X;
+ float m_1_0 = space->space.RGBtoXYZf[3] / D50_WHITE_REF_Y;
+ float m_1_1 = space->space.RGBtoXYZf[4] / D50_WHITE_REF_Y;
+ float m_1_2 = space->space.RGBtoXYZf[5] / D50_WHITE_REF_Y;
+ float m_2_0 = space->space.RGBtoXYZf[6] / D50_WHITE_REF_Z;
+ float m_2_1 = space->space.RGBtoXYZf[7] / D50_WHITE_REF_Z;
+ float m_2_2 = space->space.RGBtoXYZf[8] / D50_WHITE_REF_Z;
long n = samples;
while (n--)
float g = src[1];
float b = src[2];
- float xr = 0.43603516f / D50_WHITE_REF_X * r + 0.38511658f / D50_WHITE_REF_X * g + 0.14305115f / D50_WHITE_REF_X * b;
- float yr = 0.22248840f / D50_WHITE_REF_Y * r + 0.71690369f / D50_WHITE_REF_Y * g + 0.06060791f / D50_WHITE_REF_Y * b;
- float zr = 0.01391602f / D50_WHITE_REF_Z * r + 0.09706116f / D50_WHITE_REF_Z * g + 0.71392822f / D50_WHITE_REF_Z * b;
+ float xr = m_0_0 * r + m_0_1 * g + m_0_2 * b;
+ float yr = m_1_0 * r + m_1_1 * g + m_1_2 * b;
+ float zr = m_2_0 * r + m_2_1 * g + m_2_2 * b;
float fx = xr > LAB_EPSILON ? _cbrtf (xr) : (LAB_KAPPA * xr + 16.0f) / 116.0f;
float fy = yr > LAB_EPSILON ? _cbrtf (yr) : (LAB_KAPPA * yr + 16.0f) / 116.0f;
}
}
+static void
+rgbaf_to_Lf (const Babl *conversion,float *src,
+ float *dst,
+ long samples)
+{
+ const Babl *space = babl_conversion_get_source_space (conversion);
+ float m_1_0 = space->space.RGBtoXYZf[3] / D50_WHITE_REF_Y;
+ float m_1_1 = space->space.RGBtoXYZf[4] / D50_WHITE_REF_Y;
+ float m_1_2 = space->space.RGBtoXYZf[5] / D50_WHITE_REF_Y;
+ long n = samples;
+
+ while (n--)
+ {
+ float r = src[0];
+ float g = src[1];
+ float b = src[2];
+
+ float yr = m_1_0 * r + m_1_1 * g + m_1_2 * b;
+
+ float fy = yr > LAB_EPSILON ? _cbrtf (yr) : (LAB_KAPPA * yr + 16.0f) / 116.0f;
+
+ float L = 116.0f * fy - 16.0f;
+
+ dst[0] = L;
+
+ src += 4;
+ dst += 1;
+ }
+}
+
+static void
+rgbaf_to_Labf (const Babl *conversion,float *src,
+ float *dst,
+ long samples)
+{
+ const Babl *space = babl_conversion_get_source_space (conversion);
+ float m_0_0 = space->space.RGBtoXYZf[0] / D50_WHITE_REF_X;
+ float m_0_1 = space->space.RGBtoXYZf[1] / D50_WHITE_REF_X;
+ float m_0_2 = space->space.RGBtoXYZf[2] / D50_WHITE_REF_X;
+ float m_1_0 = space->space.RGBtoXYZf[3] / D50_WHITE_REF_Y;
+ float m_1_1 = space->space.RGBtoXYZf[4] / D50_WHITE_REF_Y;
+ float m_1_2 = space->space.RGBtoXYZf[5] / D50_WHITE_REF_Y;
+ float m_2_0 = space->space.RGBtoXYZf[6] / D50_WHITE_REF_Z;
+ float m_2_1 = space->space.RGBtoXYZf[7] / D50_WHITE_REF_Z;
+ float m_2_2 = space->space.RGBtoXYZf[8] / D50_WHITE_REF_Z;
+ long n = samples;
+
+ while (n--)
+ {
+ float r = src[0];
+ float g = src[1];
+ float b = src[2];
+
+ float xr = m_0_0 * r + m_0_1 * g + m_0_2 * b;
+ float yr = m_1_0 * r + m_1_1 * g + m_1_2 * b;
+ float zr = m_2_0 * r + m_2_1 * g + m_2_2 * b;
+
+ float fx = xr > LAB_EPSILON ? _cbrtf (xr) : (LAB_KAPPA * xr + 16.0f) / 116.0f;
+ float fy = yr > LAB_EPSILON ? _cbrtf (yr) : (LAB_KAPPA * yr + 16.0f) / 116.0f;
+ float fz = zr > LAB_EPSILON ? _cbrtf (zr) : (LAB_KAPPA * zr + 16.0f) / 116.0f;
+
+ float L = 116.0f * fy - 16.0f;
+ float A = 500.0f * (fx - fy);
+ float B = 200.0f * (fy - fz);
+
+ dst[0] = L;
+ dst[1] = A;
+ dst[2] = B;
+
+ src += 4;
+ dst += 3;
+ }
+}
+
static void
rgbaf_to_Labaf (const Babl *conversion,float *src,
float *dst,
long samples)
{
+ const Babl *space = babl_conversion_get_source_space (conversion);
+ float m_0_0 = space->space.RGBtoXYZf[0] / D50_WHITE_REF_X;
+ float m_0_1 = space->space.RGBtoXYZf[1] / D50_WHITE_REF_X;
+ float m_0_2 = space->space.RGBtoXYZf[2] / D50_WHITE_REF_X;
+ float m_1_0 = space->space.RGBtoXYZf[3] / D50_WHITE_REF_Y;
+ float m_1_1 = space->space.RGBtoXYZf[4] / D50_WHITE_REF_Y;
+ float m_1_2 = space->space.RGBtoXYZf[5] / D50_WHITE_REF_Y;
+ float m_2_0 = space->space.RGBtoXYZf[6] / D50_WHITE_REF_Z;
+ float m_2_1 = space->space.RGBtoXYZf[7] / D50_WHITE_REF_Z;
+ float m_2_2 = space->space.RGBtoXYZf[8] / D50_WHITE_REF_Z;
long n = samples;
while (n--)
float b = src[2];
float a = src[3];
- float xr = 0.43603516f / D50_WHITE_REF_X * r + 0.38511658f / D50_WHITE_REF_X * g + 0.14305115f / D50_WHITE_REF_X * b;
- float yr = 0.22248840f / D50_WHITE_REF_Y * r + 0.71690369f / D50_WHITE_REF_Y * g + 0.06060791f / D50_WHITE_REF_Y * b;
- float zr = 0.01391602f / D50_WHITE_REF_Z * r + 0.09706116f / D50_WHITE_REF_Z * g + 0.71392822f / D50_WHITE_REF_Z * b;
+ float xr = m_0_0 * r + m_0_1 * g + m_0_2 * b;
+ float yr = m_1_0 * r + m_1_1 * g + m_1_2 * b;
+ float zr = m_2_0 * r + m_2_1 * g + m_2_2 * b;
float fx = xr > LAB_EPSILON ? _cbrtf (xr) : (LAB_KAPPA * xr + 16.0f) / 116.0f;
float fy = yr > LAB_EPSILON ? _cbrtf (yr) : (LAB_KAPPA * yr + 16.0f) / 116.0f;
}
}
+static void
+Labf_to_Lf (const Babl *conversion,float *src,
+ float *dst,
+ long samples)
+{
+ long n = samples;
+
+ while (n--)
+ {
+ dst[0] = src[0];
+
+ src += 3;
+ dst += 1;
+ }
+}
+
+static void
+Labaf_to_Lf (const Babl *conversion,float *src,
+ float *dst,
+ long samples)
+{
+ long n = samples;
+
+ while (n--)
+ {
+ dst[0] = src[0];
+
+ src += 4;
+ dst += 1;
+ }
+}
+
static void
Labf_to_rgbf (const Babl *conversion,float *src,
float *dst,
long samples)
{
+ const Babl *space = babl_conversion_get_source_space (conversion);
+ float m_0_0 = space->space.XYZtoRGBf[0] * D50_WHITE_REF_X;
+ float m_0_1 = space->space.XYZtoRGBf[1] * D50_WHITE_REF_Y;
+ float m_0_2 = space->space.XYZtoRGBf[2] * D50_WHITE_REF_Z;
+ float m_1_0 = space->space.XYZtoRGBf[3] * D50_WHITE_REF_X;
+ float m_1_1 = space->space.XYZtoRGBf[4] * D50_WHITE_REF_Y;
+ float m_1_2 = space->space.XYZtoRGBf[5] * D50_WHITE_REF_Z;
+ float m_2_0 = space->space.XYZtoRGBf[6] * D50_WHITE_REF_X;
+ float m_2_1 = space->space.XYZtoRGBf[7] * D50_WHITE_REF_Y;
+ float m_2_2 = space->space.XYZtoRGBf[8] * D50_WHITE_REF_Z;
long n = samples;
while (n--)
float xr = cubef (fx) > LAB_EPSILON ? cubef (fx) : (fx * 116.0f - 16.0f) / LAB_KAPPA;
float zr = cubef (fz) > LAB_EPSILON ? cubef (fz) : (fz * 116.0f - 16.0f) / LAB_KAPPA;
- float r = 3.134274799724f * D50_WHITE_REF_X * xr -1.617275708956f * D50_WHITE_REF_Y * yr -0.490724283042f * D50_WHITE_REF_Z * zr;
- float g = -0.978795575994f * D50_WHITE_REF_X * xr +1.916161689117f * D50_WHITE_REF_Y * yr +0.033453331711f * D50_WHITE_REF_Z * zr;
- float b = 0.071976988401f * D50_WHITE_REF_X * xr -0.228984974402f * D50_WHITE_REF_Y * yr +1.405718224383f * D50_WHITE_REF_Z * zr;
+ float r = m_0_0 * xr + m_0_1 * yr + m_0_2 * zr;
+ float g = m_1_0 * xr + m_1_1 * yr + m_1_2 * zr;
+ float b = m_2_0 * xr + m_2_1 * yr + m_2_2 * zr;
dst[0] = r;
dst[1] = g;
float *dst,
long samples)
{
+ const Babl *space = babl_conversion_get_source_space (conversion);
+ float m_0_0 = space->space.XYZtoRGBf[0] * D50_WHITE_REF_X;
+ float m_0_1 = space->space.XYZtoRGBf[1] * D50_WHITE_REF_Y;
+ float m_0_2 = space->space.XYZtoRGBf[2] * D50_WHITE_REF_Z;
+ float m_1_0 = space->space.XYZtoRGBf[3] * D50_WHITE_REF_X;
+ float m_1_1 = space->space.XYZtoRGBf[4] * D50_WHITE_REF_Y;
+ float m_1_2 = space->space.XYZtoRGBf[5] * D50_WHITE_REF_Z;
+ float m_2_0 = space->space.XYZtoRGBf[6] * D50_WHITE_REF_X;
+ float m_2_1 = space->space.XYZtoRGBf[7] * D50_WHITE_REF_Y;
+ float m_2_2 = space->space.XYZtoRGBf[8] * D50_WHITE_REF_Z;
long n = samples;
while (n--)
float xr = cubef (fx) > LAB_EPSILON ? cubef (fx) : (fx * 116.0f - 16.0f) / LAB_KAPPA;
float zr = cubef (fz) > LAB_EPSILON ? cubef (fz) : (fz * 116.0f - 16.0f) / LAB_KAPPA;
- float r = 3.134274799724f * D50_WHITE_REF_X * xr -1.617275708956f * D50_WHITE_REF_Y * yr -0.490724283042f * D50_WHITE_REF_Z * zr;
- float g = -0.978795575994f * D50_WHITE_REF_X * xr +1.916161689117f * D50_WHITE_REF_Y * yr +0.033453331711f * D50_WHITE_REF_Z * zr;
- float b = 0.071976988401f * D50_WHITE_REF_X * xr -0.228984974402f * D50_WHITE_REF_Y * yr +1.405718224383f * D50_WHITE_REF_Z * zr;
+ float r = m_0_0 * xr + m_0_1 * yr + m_0_2 * zr;
+ float g = m_1_0 * xr + m_1_1 * yr + m_1_2 * zr;
+ float b = m_2_0 * xr + m_2_1 * yr + m_2_2 * zr;
dst[0] = r;
dst[1] = g;
"linear", Labf_to_rgbf,
NULL
);
+ babl_conversion_new (
+ babl_format ("RGBA float"),
+ babl_format ("CIE Lab float"),
+ "linear", rgbaf_to_Labf,
+ NULL
+ );
babl_conversion_new (
babl_format ("RGBA float"),
babl_format ("CIE Lab alpha float"),
"linear", Labaf_to_rgbaf,
NULL
);
+ babl_conversion_new (
+ babl_format ("Y float"),
+ babl_format ("CIE L float"),
+ "linear", Yf_to_Lf,
+ NULL
+ );
+ babl_conversion_new (
+ babl_format ("YA float"),
+ babl_format ("CIE L float"),
+ "linear", Yaf_to_Lf,
+ NULL
+ );
babl_conversion_new (
babl_format ("YA float"),
babl_format ("CIE L alpha float"),
"linear", Yaf_to_Laf,
NULL
);
+ babl_conversion_new (
+ babl_format ("RGBA float"),
+ babl_format ("CIE L float"),
+ "linear", rgbaf_to_Lf,
+ NULL
+ );
+ babl_conversion_new (
+ babl_format ("CIE Lab float"),
+ babl_format ("CIE L float"),
+ "linear", Labf_to_Lf,
+ NULL
+ );
+ babl_conversion_new (
+ babl_format ("CIE Lab alpha float"),
+ babl_format ("CIE L float"),
+ "linear", Labaf_to_Lf,
+ NULL
+ );
babl_conversion_new (
babl_model ("RGBA"),
babl_model ("CIE LCH(ab)"),
babl_component ("A"),
NULL);
+ babl_format_new (
+ "name", "CIE L float",
+ babl_model ("CIE Lab"),
+ babl_type ("float"),
+ babl_component ("CIE L"),
+ NULL);
+
babl_format_new (
"name", "CIE L alpha float",
babl_model ("CIE Lab alpha"),
{
float alpha = (*(float *) (src + 4));
- *(float *) dst = ((*(float *) src) / alpha);
+ if (alpha == 0.0f)
+ *(float *) dst = 0.0f;
+ else
+ *(float *) dst = ((*(float *) src) / alpha);
dst += 4;
src += 4;
*(float *) dst = alpha;
{
float alpha = (*(float *) (src + 4));
- *(float *) dst = ((*(float *) src) / alpha);
+ if (alpha == 0.0f)
+ *(float *) dst = 0.0f;
+ else
+ *(float *) dst = ((*(float *) src) / alpha);
dst += 4;
src += 4;
*(float *) dst = alpha;
{
float alpha = (((unsigned short *) src)[3]) / 65535.0;
int c;
+ float recip_alpha;
+
+ if (alpha == 0.0f)
+ recip_alpha = 10000.0;
+ else
+ recip_alpha = 1.0/alpha;
for (c = 0; c < 3; c++)
{
- (*(float *) dst) = (*(unsigned short *) src / 65535.0) / alpha;
+ (*(float *) dst) = (*(unsigned short *) src / 65535.0) * recip_alpha;
dst += 4;
src += 2;
}
#define FLT_ONE 0x3f800000 // ((union {float f; int i;}){1.0f}).i
#define FLT_MANTISSA (1<<23)
+static inline float
+sse_max_component (__v4sf x) {
+ __v4sf s;
+ __v4sf m;
+
+ /* m = [max (x[3], x[1]), max (x[2], x[0])] */
+ s = (__v4sf) _mm_shuffle_epi32 ((__m128i) x, _MM_SHUFFLE(0, 0, 3, 2));
+ m = _mm_max_ps (x, s);
+
+ /* m = [max (m[1], m[0])] = [max (max (x[3], x[1]), max (x[2], x[0]))] */
+ s = (__v4sf) _mm_shuffle_epi32 ((__m128i) m, _MM_SHUFFLE(0, 0, 0, 1));
+ m = _mm_max_ps (m, s);
+
+ return m[0];
+}
+
static inline __v4sf
sse_init_newton (__v4sf x, double exponent, double c0, double c1, double c2)
{
sse_pow_1_24 (__v4sf x)
{
__v4sf y, z;
+ if (sse_max_component (x) > 1024.0f) {
+ /* for large values, fall back to a slower but more accurate version */
+ return _mm_set_ps (expf (logf (x[3]) * (1.0f / 2.4f)),
+ expf (logf (x[2]) * (1.0f / 2.4f)),
+ expf (logf (x[1]) * (1.0f / 2.4f)),
+ expf (logf (x[0]) * (1.0f / 2.4f)));
+ }
y = sse_init_newton (x, -1./12, 0.9976800269, 0.9885126933, 0.5908575383);
x = _mm_sqrt_ps (x);
/* newton's method for x^(-1/6) */
sse_pow_24 (__v4sf x)
{
__v4sf y, z;
+ if (sse_max_component (x) > 16.0f) {
+ /* for large values, fall back to a slower but more accurate version */
+ return _mm_set_ps (expf (logf (x[3]) * 2.4f),
+ expf (logf (x[2]) * 2.4f),
+ expf (logf (x[1]) * 2.4f),
+ expf (logf (x[0]) * 2.4f));
+ }
y = sse_init_newton (x, -1./5, 0.9953189663, 0.9594345146, 0.6742970332);
/* newton's method for x^(-1/5) */
z = splat4f (1.f/5.f) * x;